package com.quanyue.haircut.support;

import com.fasterxml.jackson.core.type.TypeReference;
import com.google.common.base.Charsets;
import com.quanyue.auto.cache.core.CacheService;
import com.quanyue.auto.util.AssertUtils;
import com.quanyue.auto.web.Principal;
import com.quanyue.auto.web.UserDetailService;
import com.quanyue.auto.web.WebProperties;
import com.quanyue.haircut.domain.constant.UserRole;
import com.quanyue.haircut.domain.entity.Manager;
import com.quanyue.haircut.user.mapper.ManagerMapper;
import com.quanyue.haircut.user.service.UserService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Type;
import java.util.Base64;
import java.util.Map;
import java.util.Set;

@Component
public class UserDetailServiceImpl implements UserDetailService {

    private final UserService userService;
    private final CacheService cacheService;
    private final WebProperties properties;
    private final ManagerMapper managerMapper;

    @Autowired
    public UserDetailServiceImpl(UserService userService,
                                 ManagerMapper managerMapper,
                                 CacheService cacheService,
                                 WebProperties properties) {
        this.userService = userService;
        this.managerMapper = managerMapper;
        this.cacheService = cacheService;
        this.properties = properties;
    }

    @Override
    public Object findUser(Principal contextUser) {
        return userService.findById(contextUser.getId());
    }

    @Override
    public Principal findPrincipal(String token) {
        if (token.length() == 32) {
            Type type = new TypeReference<Map <String, Principal>>() {
            }.getType();
            Map<String, Principal> sessionCache = cacheService.get(properties.getCacheKey(), type);
            return sessionCache.get(token);
        } else {
            String[] codes = new String(Base64.getDecoder().decode(token), Charsets.UTF_8).split(",");
            AssertUtils.isTrue(codes.length == 2, "非法访问");
            Manager manager = managerMapper.findOne(Integer.valueOf(codes[1]));
            if (manager == null) {
                return null;
            }
            Principal principal = new Principal();
            principal.setId(manager.getId());
            principal.setRole(UserRole.MANAGER);
            principal.setMerchantNo(manager.getMerchantNo());
            return principal;
        }
    }

    @Override
    public Set <String> findPrimitives(Principal principal) {
        return null;
    }
}
